﻿using ERP.Common.Util;
using ERP.SYS.Interfaces;
using ERP.SYS.Model.Entity;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;

namespace ERP.Common.Middleware;

public class CustomAuthenticationMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<CustomAuthenticationMiddleware> _logger;
    private readonly IRoleService _roleService;

    private List<SysRolePermission> _rolePermissions;

    public CustomAuthenticationMiddleware(
      RequestDelegate next,
      ILogger<CustomAuthenticationMiddleware> logger,
      IRoleService roleService)
    {
        _next = next;
        _logger = logger;
        _roleService = roleService;

        RefreshRolePermissions(true);
    }

    private void RefreshRolePermissions(bool isFocre = false)
    {
        // if not force to refresh role permission and role permission have value 
        // directly return
        if (!isFocre)
        {
            return;
        }

        _rolePermissions = _roleService.GetRolePermissions();
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // 在这里添加请求拦截逻辑
        _logger.LogInformation("Request intercepted: {Path}", context.Request.Path);

        // 验证请求头中的 Authorization 字段
        long roleId = MathPath(context.Request.Path);

        if (roleId != -1)
        {

            if (!context.Request.Headers.TryGetValue("Authorization", out var authorization))
            {
                _logger.LogWarning("Authorization header not found");
                context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                await context.Response.WriteAsync("Authorization header is required");
                return;
            }

            Dictionary<string, object> data = JwtUtil.ParseJwtMetadata(authorization);

            if (int.Parse(data["roleId"].ToString()) != roleId)
            {
                _logger.LogWarning("Insufficient authority");
                context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                await context.Response.WriteAsync("Insufficient authority");
                return;
            }
        }

        // 记录请求方法和路径
        _logger.LogInformation("Request method: {Method}, Path: {Path}", context.Request.Method, context.Request.Path);

        // 继续处理请求
        await _next(context);

        // 在这里添加响应拦截逻辑
        _logger.LogInformation("Response status code: {StatusCode}", context.Response.StatusCode);
    }

    private long MathPath(string path)
    {
        foreach (var item in _rolePermissions)
        {
            if (item.Permission.Path == path)
            {
                return item.Role.RoleId;
            }
        }

        return -1;
    }
}
